<?php

namespace support;

use GuzzleHttp\Client;
use Qiniu\Auth;
use Qiniu\Storage\BucketManager;
use Qiniu\Storage\UploadManager;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;

class PackZip
{
    /**
     * 下载七牛云的文件到本地并打包压缩
     * @param array $fileList 要下载的文件列表，每个元素包含文件的url和保存路径
     * @param string $zipFileName 压缩包的文件名
     * @return string|false 成功返回压缩包的文件名，失败返回false
     */
    public static function packNetFile2Local($urlList, $packName)
    {
        Log::info('开始下载文件');
        $localFile = [];
        // 循环下载文件数组
        foreach ($urlList as $k => $v) {
            // 重命名文件 时间戳+ 唯一id+ 后缀名
            $filename =  time() . '-' . uniqid() . '.' . pathinfo($v['remoteFile'], PATHINFO_EXTENSION); //  
            $path = $v['localFile'];
            if (!is_dir($path)) {
                mkdir($path, 0777, true);
            }
            $localOne = self::netFile2LocalFile($v['remoteFile'], $path . $filename);
            Log::info('下载文件到本地完成' . $localOne);
            if ($localOne) {
                $localFile[] = $localOne;
            }
        }
        Log::info('下载文件到本地完成' . json_encode($localFile));
        $tmpDir = public_path() . '/' . 'download' . '/';
        if ($localFile) {
            // 压缩
            $zipname = self::getZipName($tmpDir, $packName);

            $zip = new \ZipArchive;
            // // 打开ZIP文件用于写入
            if ($zip->open($zipname, \ZipArchive::CREATE) === TRUE) {
                // 递归遍历目录并添加到ZIP文件
                self::addFilesToZip($tmpDir . '/' . $packName, $zip);
                // 关闭ZIP文件
                $zip->close();
                // echo "Directory has been successfully packed into zip.";
                $res = self::uploadToQiniu($zipname);
                // $res = true;
                if ($res) {
                    // 上传成功之后删除本地文件夹和压缩包
                    self::deleteZipFile($zipname);
                    self::deleteDirectory($tmpDir . '/' . $packName);
                    // }
                    return $res;
                } else {
                    echo "Failed to create zip file.";
                }
            } else {
                return false;
            }
        }
    }
    /**
     * 废弃
     * @param $tmpDir  临时目录
     * @param $fileList 文件列表
     * @param $packName 打包后的文件名
     */
    public static function packFile($tmpDir, $fileList, $packName)
    {
        $localFile = [];
        foreach ($fileList as $k => $v) {
            // $filename = $v['name'] . '.' . pathinfo($v['path'], PATHINFO_EXTENSION);
            $filename = time() . '.' . pathinfo($v, PATHINFO_EXTENSION); //  文件名.后缀名
            // 这个是文件中间目录
            $middleDir = dirname(parse_url($v, PHP_URL_PATH)); //. $middleDir . '/'

            $path = rtrim($tmpDir, '/') . '/' . $packName . $middleDir . '/';
            if (!is_dir($path)) {
                mkdir($path, 0777, true);
            }

            $localOne = self::netFile2LocalFile($v, $path  . $filename);
            if ($localOne) {
                $localFile[] = $localOne;
            }
        }
        if ($localFile) {
            // 压缩
            $zipname = self::getZipName($tmpDir, $packName);
            var_export('删除路径：' . $tmpDir . '\\' . $packName);
            var_export('删除文件：' . $zipname);
            $zip = new \ZipArchive;
            // 打开ZIP文件用于写入
            if ($zip->open($zipname, \ZipArchive::CREATE) === TRUE) {
                // 递归遍历目录并添加到ZIP文件
                self::addFilesToZip($tmpDir . '/' . $packName, $zip);
                // 关闭ZIP文件
                $zip->close();
                // echo "Directory has been successfully packed into zip.";
                $res = self::uploadToQiniu($zipname);
                // $res = true;
                if ($res) {
                    // 上传成功之后删除本地文件夹和压缩包
                    self::deleteZipFile($zipname);
                    self::deleteDirectory($tmpDir . '/' . $packName);
                }
                return $res;
            } else {
                echo "Failed to create zip file.";
            }
        } else {
            return false;
        }
    }

    // 递归函数，用于将目录和文件添加到ZIP文件
    public static function addFilesToZip($folder, $zip)
    {
        $handle = opendir($folder);
        while (($file = readdir($handle)) !== false) {
            if ($file != '.' && $file != '..') {
                $filePath = $folder . '/' . $file;
                if (is_dir($filePath)) {
                    // 如果是目录，则递归调用
                    self::addFilesToZip($filePath, $zip);
                } else {
                    // 如果是文件，则添加到ZIP文件
                    $zip->addFile($filePath, $filePath);
                }
            }
        }
        closedir($handle);
    }
    /**
     * 获取ZIP文件的完整路径名
     *
     * @param string $tmpDir 临时目录路径
     * @param string $packName ZIP文件的基本名称（不包含扩展名）
     * @return string 返回ZIP文件的完整路径名，包括目录路径、基本名称和扩展名（.zip）
     */
    public static function getZipName($tmpDir, $packName)
    {
        // 使用 rtrim 函数去除临时目录路径末尾的斜杠，然后拼接上打包文件名和 .zip 扩展名，返回完整的ZIP文件路径名
        return rtrim($tmpDir, '/') . '/' . $packName . '.zip';
    }

    // 删除ZIP文件
    public static function deleteZipFile($zipFilePath)
    {
        if (file_exists($zipFilePath)) {
            unlink($zipFilePath);
            echo "ZIP file deleted: " . $zipFilePath;
        } else {
            echo "ZIP file does not exist: " . $zipFilePath;
        }
    }

    // 删除目录及其内容
    public static function deleteDirectory($dirPath)
    {
        if (is_dir($dirPath)) {
            // RecursiveIteratorIterator
            // RecursiveDirectoryIterator
            $files = new RecursiveIteratorIterator(
                new RecursiveDirectoryIterator($dirPath, RecursiveDirectoryIterator::SKIP_DOTS),
                RecursiveIteratorIterator::CHILD_FIRST
            );

            foreach ($files as $fileinfo) {
                $action = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
                $action($fileinfo->getRealPath());
            }

            rmdir($dirPath);
            echo "Directory deleted: " . $dirPath;
        } else {
            echo "Directory does not exist: " . $dirPath;
        }
    }


    /**
     * 网络文件路径转换为本地文件路径
     * @param $fileUrl 网络文件路径
     * @param $filePath 本地文件路径
     */
    private static function netFile2LocalFile($url, $directory)
    {
        $client = new Client();
        try {
            $response = $client->get($url, [
                'sink' => $directory
            ]);
            if ($response->getStatusCode() === 200) {
                return $directory;
            } else {
                return $response->getStatusCode();
            }
        } catch (\Exception $e) {
            return $e->getMessage();
        }
    }

    // 上传到七牛云并返回新的下载链接地址
    public static function uploadToQiniu($zipFileName)
    {
        $accessKey = config('app.qiniu.accessKey');
        $secretKey = config('app.qiniu.secretKey');
        $bucket = config('app.qiniu.bucket');
        $key = date('Y/m/d') . '/' . basename($zipFileName);

        $auth = new Auth($accessKey, $secretKey);
        $token = $auth->uploadToken($bucket);

        $uploadMgr = new UploadManager();
        list($ret, $err) = $uploadMgr->putFile($token, $key, $zipFileName);
        if ($err !== null) {
            // 处理上传出错情况
            return false;
        }
        // 构建新的七牛云下载链接地址
        $domain = config('app.qiniu.domain');;
        $newDownloadUrl = $domain . '/' . $key;
        return $newDownloadUrl;
    }
}
